﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics.Contracts;
using System.IO;
using Protocol;
namespace MDS
{
    abstract public class DBFQuotationProviderBase : IQuotationProvider
    {


        public event MessageHandler<GWMKTBasicInfoANS> OnBasicMsgReceived;

        public event MessageHandler<GWMKTBidAskANS> OnBidMsgReceived;

        public event MessageHandler<GWMKTTicksANS> OnTickMsgReceived;

        public event MultiMessageHandler<IMessage> MessagesReceived;

        protected DBFQuotationProviderConfig _config;

        protected System.Timers.Timer _checkDBFTimer;
        protected DateTime? _DBFLastWriteTime;
        protected bool _isReading = false;
        protected DateTime? _lastTradeTime;

        #region 构造函数
        public DBFQuotationProviderBase(DBFQuotationProviderConfig config)
        {
            Contract.Requires(config != null);

            this._config = config;
            this._checkDBFTimer = new System.Timers.Timer()
            {
                Interval = this._config.CheckDBFIntervalMS,
                AutoReset = false,
                Enabled = false
            };
            this._checkDBFTimer.Elapsed += new System.Timers.ElapsedEventHandler(_checkDBFTimer_Elapsed);
        }
        #endregion
        void _checkDBFTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            string file = this._config.DBFFileFullPath;
            if (this._isReading || !File.Exists(file))
                return;
            try
            {
                
                DateTime lastWriteTime = File.GetLastWriteTime(file);
                if (!this._DBFLastWriteTime.HasValue
                    || lastWriteTime > this._DBFLastWriteTime)
                {
                    this._isReading = true;
                    IEnumerable<IMessage> messages;
                    DateTime? tradeTime;
                    bool succeed = tryReadDbfFile(file, out messages, out tradeTime);
                    if (succeed)
                    {
                        if (messages != null)
                        {
                            foreach (var msg in messages)
                            {
                                onMsgReceived(msg);
                            }
                            onMessagesReceived(messages);
                        }
                        this._lastTradeTime = tradeTime;
                    }
                }
            }
            catch (Exception ex)
            {
                Log.Debug(ex.StackTrace);
            }
            finally
            {
                this._isReading = false;
            }
        }

        protected abstract bool tryReadDbfFile(string file, out IEnumerable<IMessage> messages,out DateTime? tradeTime);


        protected void onMessagesReceived(IEnumerable<IMessage> messages)
        {
            MultiMessageHandler<IMessage> handler = this.MessagesReceived;
            if (handler != null)
                handler(messages);
        }
        protected void onMsgReceived(Protocol.IMessage message)
        {
            if (message is Protocol.GWMKTBasicInfoANS)
                onBasicMsgReceived(message as Protocol.GWMKTBasicInfoANS);
            else if (message is Protocol.GWMKTBidAskANS)
                onBidMsgReceived(message as Protocol.GWMKTBidAskANS);
            else if (message is Protocol.GWMKTTicksANS)
                onTickMsgReceived(message as Protocol.GWMKTTicksANS);
        }
        protected void onBasicMsgReceived(Protocol.GWMKTBasicInfoANS basicMsg)
        {
            MessageHandler<Protocol.GWMKTBasicInfoANS> eventHandler = this.OnBasicMsgReceived;
            if (eventHandler != null)
            {
                try
                {
                    eventHandler(basicMsg);
                }
                catch (Exception ex)
                {
                    Log.Debug(ex);
                }
            }
        }
        protected void onBidMsgReceived(Protocol.GWMKTBidAskANS bidMsg)
        {
            MessageHandler<Protocol.GWMKTBidAskANS> eventHandler = this.OnBidMsgReceived;
            if (eventHandler != null)
            {
                try
                {
                    eventHandler(bidMsg);
                }
                catch (Exception ex)
                {
                    Log.Debug(ex);
                }
            }
        }
        protected void onTickMsgReceived(Protocol.GWMKTTicksANS tickMsg)
        {
            MessageHandler<Protocol.GWMKTTicksANS> eventHandler = this.OnTickMsgReceived;
            if (eventHandler != null)
            {
                try
                {
                    eventHandler(tickMsg);
                }
                catch (Exception ex)
                {
                    Log.Debug(ex);
                }
            }
        }


        public void Start()
        {
            this._checkDBFTimer.Enabled = true;
        }

        public void Stop()
        {
            this._checkDBFTimer.Enabled = false;
        }

        public void Clear()
        {
            throw new NotImplementedException();
        }




    }
}
